public class Fraction {
    public static final Fraction ZERO = new Fraction(0, 1);
    //分子
    private int numerator;
    //分母
    private int denominator;
    //无参构造
    public Fraction(){

    }
    //构造函数构造分数
    public Fraction(int numerator, int denominator) {
        this.numerator = numerator;
        this.denominator = denominator;
        simplify();
    }

    /**
     * 比较两个数
     * @param a 数字1
     * @param b 数字2
     * @return 返回 1 代表 a > b;2 代表 a = b;3 代表 a < b;
     */
    public int compare(Fraction a,Fraction b){
        int a_numerator = a.numerator * b.denominator;
        int b_numerator = b.numerator * a.denominator;
        if(a_numerator>b_numerator)return 1;
        if(a_numerator==b_numerator)return 2;
        return 3;
    }

    /**
     * 与其他分数做加法
     * @param other 其他分数
     * @return 返回相加后的值
     */
    public Fraction add(Fraction other) {
        int resultNumerator = this.numerator * other.denominator + other.numerator * this.denominator;
        int resultDenominator = this.denominator * other.denominator;
        return new Fraction(resultNumerator, resultDenominator);
    }
    /**
     * 与其他分数做减法
     * @param other 其他分数
     * @return 返回相减后的值
     */
    public Fraction subtract(Fraction other) {
        int resultNumerator = this.numerator * other.denominator - other.numerator * this.denominator;
        int resultDenominator = this.denominator * other.denominator;
        return new Fraction(resultNumerator, resultDenominator);
    }
    /**
     * 与其他分数做乘法
     * @param other 其他分数
     * @return 返回相乘后的值
     */
    public Fraction multiply(Fraction other) {
        int resultNumerator = this.numerator * other.numerator;
        int resultDenominator = this.denominator * other.denominator;
        return new Fraction(resultNumerator, resultDenominator);
    }
    /**
     * 与其他分数做除法
     * @param other 其他分数
     * @return 返回相除后的值
     */
    public Fraction divide(Fraction other) {
        if (other.numerator == 0) {
            throw new ArithmeticException("Division by zero");
        }
        int resultNumerator = this.numerator * other.denominator;
        int resultDenominator = this.denominator * other.numerator;
        return new Fraction(resultNumerator, resultDenominator);
    }

    /**
     * 幂运算
     * @param exponent 指数
     * @return 返回幂运算结果
     */
    public Fraction power(Fraction exponent) {
        int resultNumerator = 1;
        int resultDenominator = 1;

        while (exponent.numerator > 0) {
            if ((exponent.numerator & 1) == 1) {
                resultNumerator = multiply(resultNumerator, this.numerator);
                resultDenominator = multiply(resultDenominator, this.denominator);
            }
            exponent.numerator >>= 1;
            this.numerator = multiply(this.numerator, this.numerator);
            this.denominator = multiply(this.denominator, this.denominator);
        }

        return new Fraction(resultNumerator, resultDenominator);
    }

    /**
     * 重载multiply方法
     * @param a 整数1
     * @param b 整数2
     * @return 返回两个整数的乘积
     */
    private int multiply(int a, int b) {
        return a * b;
    }

    /**
     * 分数有理化
     */
    private void simplify() {
        int gcd = greatestCommonDivisor(Math.abs(numerator), Math.abs(denominator));
        numerator /= gcd;
        denominator /= gcd;
    }

    /**
     *求两个数的最大公约数
     * @param a 数1
     * @param b 数2
     * @return 返回这两个数的最大公约数
     */
    private int greatestCommonDivisor(int a, int b) {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }

    /**
     * 解析字符串
     * @param fractionStr 待解析的字符串
     * @return 返回解析字符串后所得的分数
     */
    public static Fraction parseFraction(String fractionStr) {
        //定义解析器的状态
        final int STATE_INTEGER = 0;
        final int STATE_FRACTION = 1;
        final int STATE_DECIMALS = 2;

        //初始化状态、分子和分母
        int state = STATE_INTEGER;
        int numerator = 0;
        int denominator = 0;

        //循环遍历字符串并检查状态
        for (int i = 0; i < fractionStr.length(); i++) {
            //如果字符是'/'，则将状态设置为分数
            if(fractionStr.charAt(i) == '/')
                state = STATE_FRACTION;
            //如果字符是'.'，将状态设置为小数
            if(fractionStr.charAt(i) == '.')
                state = STATE_DECIMALS;
        }

        switch (state){
            //如果状态为整数，则设置分子为该数，分母为1
            case STATE_INTEGER:
                numerator = Integer.parseInt(fractionStr);
                denominator = 1;
                break;
            //如果状态为分数，则将分子和分母设置为分数的部分
            case STATE_FRACTION:
                String[] parts = fractionStr.split("/");
                numerator = Integer.parseInt(parts[0]);
                denominator = Integer.parseInt(parts[1]);
                break;
            //如果状态为小数，则将分子和分母设置为分数的部分
            case STATE_DECIMALS:
                String[] parts2 = fractionStr.split(".");
                numerator = Integer.parseInt(parts2[0]+parts2[1]);
                denominator = (int) Math.pow(10, parts2[1].length());
                break;
        }
        //如果分母为0，则抛出异常
        if(denominator == 0){
            throw new ArithmeticException("denominator cannot be zero");
        }
        //返回一个带有分子和分母的新分数
        return new Fraction(numerator, denominator);
    }


    public int getNumerator() {
        return numerator;
    }

    @Override
    public String toString() {
        if(denominator == 1)
            return numerator + "";
        else
            return numerator + "/" + denominator;
    }
}
